﻿using System;
using System.Collections.Generic;

namespace Panda.UI.Runtime
{
    public class DefaultRouter : IRouter
    {
        
        private readonly Dictionary<string, ILayer> _registerLayers = new ();
        private ILayer _defaultLayer = null;
        
        public void Register(string pageId, IPage page, string layerId = null)
        {
            if (TryGetLayer(layerId, out var layer))
            {
                page.Router = this;
                layer.Register(pageId, page);
            }
        }

        public void Register(string layerId, ILayer layer)
        {
            layer.Router = this;
            _registerLayers[layerId] = layer;
            _defaultLayer ??= layer;
        }

        public IPage GetCurrentPage(string layerId = null)
        {
            if (TryGetLayer(layerId, out var layer))
            {
                return layer.CurrentPage;
            }

            return null;
        }

        public void ReLaunch(string pageId, object data, Action success, Action fail, Action complete, string layerId = null)
        {
            if (TryGetLayer(layerId, out var layer))
            {
                layer.ReLaunch(pageId, data, success, fail, complete);
                return;
            }
            
            fail?.Invoke();
            complete?.Invoke();
        }

        public void RedirectTo(string pageId, object data, Action success, Action fail, Action complete, string layerId = null)
        {
            if (TryGetLayer(layerId, out var layer))
            {
                layer.RedirectTo(pageId, data, success, fail, complete);
                return;
            }
     
            fail?.Invoke();
            complete?.Invoke();
        }

        public void NavigateTo(string pageId, object data, Action success, Action fail, Action complete, bool createNewIfInHistory, string layerId = null)
        {
            if (TryGetLayer(layerId, out var layer))
            {
                layer.NavigateTo(pageId, data, success, fail, complete, createNewIfInHistory);
                return;
            }
            
            fail?.Invoke();
            complete?.Invoke();
        }

        public void NavigateBack(Action success, Action fail, Action complete, string layerId = null)
        {
            if (TryGetLayer(layerId, out var layer))
            {
                layer.NavigateBack(success, fail, complete);
                return;
            }
            
            fail?.Invoke();
            complete?.Invoke();
        }

        private bool TryGetLayer(string layerId, out ILayer result)
        {
            if (string.IsNullOrEmpty(layerId))
            {
                result = _defaultLayer;
                return result != null;
            }

            return _registerLayers.TryGetValue(layerId, out result);
        }
    }
}